package 类加载器.类的初始化阶段;

import org.junit.Test;

import java.util.Random;

/**
 * <P> @Author: ideaAdmin
 * <P> TODO: Class
 * <P> TODO:
 * TODO 4.当使用java.lang.reflect包中的方法反射类的方法时。比如：Class.forName("com.atguigu.java.Test")
 * <p>
 * TODO 5．当初始化子类时，如果发现其父类还没有进行过初始化，则需要先触发其父类的初始化。
 * <p>
 *
 *     TODO 针对5，补充说明：
 * TODO 当Java虚拟机初始化一个类时，要求它的所有父类都已经被初始化，但是这条规则并不适用于接口。
 * TODO >在初始化一个类时，并不会先初始化它所实现的接口
 * TODO >在初始化一个接口时，并不会先初始化它的父接口
 *
 * TODO 因此，一个父接口并不会因为它的子接口或者实现类的初始化而初始化。只有当程序首次使用特定接口的静态字段时，才会导致该接口的初始化
 *
 * TODO 6．如果一个接口定义了default方法，那么直接实现或者间接实现该接口的类的初始化，该接口要在其之前被初始化。
 * <p>
 *
 * TODO 7．当虚拟机启动时，用户需要指定一个要执行的主类（包含main（）方法的那个类），虚拟机会先初始化这个主类。
 * <p>
 * TODO 8．当初次调用 MethodHandle 实例时，初始化该 MethodHandle 指向的方法所在的类。（涉及解析REF_getStatic、REF_putStatic、REF_invokeStatic方法句柄对应的类）
 * <P> Date: 2022/3/28:20:25
 * <P> Date: 2022/3/28:20:42
 * <P> Description:
 */
//-XX:+TraceClassLoading
public class ActiveUse3 {
    static {
        System.out.println("ActiveUse3.static initializer");
    }
    public static void main(String[] args) {
        //TODO 7
        System.out.println("htllo");
    }

    @Test
    public void test() {
        try {
            Class<?> aClass = Class.forName("类加载器.类的初始化阶段.Order");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test1() {
        System.out.println(Son.num);
    }

    @Test
    public void test2() {
        //只会触发自己的初始化 不会触发继承接口的初始化
        System.out.println(CompareC.i);
    }


    @Test
    public void test3() {
        //子类继承接口的default方法 接口也会被初始化
        System.out.println(Son.num);
    }


}

class Father {
    static {
        System.out.println("Father.static initializer");
    }
}

class Son extends Father implements CompareB {
    static {
        System.out.println("Son.static initializer");
    }

    public static int num = 1;
}


interface CompareB {
    public static final Thread t = new Thread() {
        {
            System.out.println("CompareB initializer");
        }
    };

    public default void method1(){
        System.out.println("CompareB接口的.method1");
    }
}

interface CompareC extends CompareB{
    public static final Thread t = new Thread() {
        {
            System.out.println("CompareC initializer");
        }
    };

    public static final int i = new Random().nextInt(10);
}
